<template>
  <z-modal
    :title="name + '选择'"
    :width="width"
    v-bind="modalOption"
    @ok="handleOk"
    @cancel="handleCancel"
  >
    <a-row :gutter="18">
      <a-col :span="16">
        <!-- 查询区域 -->
        <div class="mb-2">
          <a-form layout="inline" class="table-page-search-form ">
            <a-row :gutter="24">
              <a-col :span="12">
                <a-form-item :label="(queryParamText||name)">
                  <a-input v-model="queryParam[queryParamCode||valueKey]" :placeholder="'请输入' + (queryParamText||name)" @pressEnter="searchQuery"/>
                </a-form-item>
              </a-col>
              <a-col :span="8">
                <a-form-item>
                  <a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
                  <a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button>
                </a-form-item>
              </a-col>
            </a-row>
          </a-form>
        </div>
        <vxe-grid
          ref="vxeTable"
          :id="rowKey"
          :height="300"
          :row-config="{keyField:rowKey}"
          :checkbox-config="{trigger:'row',reserve: true}"
          :radio-config="{trigger:'row'}"
          :toolbarConfig="false"
          v-bind="gridOptions"
          v-on="listeners"
        >
        </vxe-grid>
      </a-col>
      <a-col :span="8">
          <div>
            <span class="mb-2" style="display: inline-block;height: 40px;line-height: 40px;font-size: 16px;font-weight: 600;">{{'已选' + name}}</span>
            <vxe-grid
              border
              :row-config="{keyField:rowKey}"
              :height="260"
              :columns="selectedTable.columns || []"
              :data="selectedTable.dataSource || []"
            >
              <template #action="{ row,rowIndex }">
                <a @click="handleDeleteSelected(row, rowIndex)">删除</a>
              </template>
            </vxe-grid>
          </div>
      </a-col>
    </a-row>
  </z-modal>
</template>

<script>
import { getAction } from '@/services/manage'
import VxeTableListMixin from '@/mixins/VxeTableListMixin'
import Criteria from '@/utils/criteria'
import { OPERATOR } from '@/store/mutation-types'
import ModalMixins from '@/mixins/ModalMixins'
export default {
  name: 'JSelectBizComponentModal',
  mixins: [VxeTableListMixin, ModalMixins],
  props: {
    value: {
      type: Array,
      default: () => []
    },
    valueKey: {
      type: String,
      required: true
    },
    multiple: {
      type: Boolean,
      default: true
    },
    width: {
      type: Number,
      default: 900
    },

    name: {
      type: String,
      default: ''
    },
    listUrl: {
      type: String,
      required: true,
      default: ''
    },
    // 根据 value 获取显示文本的地址，例如存的是 username，可以通过该地址获取到 realname
    valueUrl: {
      type: String,
      default: ''
    },
    displayKey: {
      type: String,
      default: null
    },
    columns: {
      type: Array,
      required: true,
      default: () => []
    },
    // 查询条件Code
    queryParamCode: {
      type: String,
      default: null
    },
    // 查询条件文字
    queryParamText: {
      type: String,
      default: null
    },
    rowKey: {
      type: String,
      default: 'id'
    }
  },
  data() {
    return {
      innerValue: [],
      // 已选择列表
      selectedTable: {
        pagination: false,
        scroll: { y: 240 },
        columns: [
          {
            ...this.columns[1]
          },
          {
            title: '操作',
            field: 'action',
            slots: { default: 'action' },
            align: 'center',
            width: 60
          }
        ],
        dataSource: []
      },
      url: { list: this.listUrl },
      options_: [],
      dataSourceMap: {},
      dataSource: [],
      proxyConfig: {
        autoLoad: false
      },
      pagerConfig: {
        pageSize: 5,
        pageSizes: [5, 10, 20, 30]
      }
    }
  },
  watch: {
    value: {
      deep: true,
      immediate: true,
      handler(val) {
        this.selectedRowKeys = []
        this.queryOptionsByValue(val)
      }
    },
    dataSource: {
      deep: true,
      handler(val) {
        this.setTableChecked()
      }
    },
    selectedRowKeys: {
      immediate: true,
      deep: true,
      handler(val) {
        this.selectedTable.dataSource = val.map(key => { // 选中行变化时，重新设置右侧数据
          for (const data of this.dataSource) {
            if (data[this.rowKey] === key) {
              return data
            }
          }
          for (const data of this.selectedTable.dataSource) {
            if (data[this.rowKey] === key) {
              return data
            }
          }
          console.warn('未找到选择的行信息，key：' + key)
          return {}
        })
      }
    }
  },
  methods: {
    async show() {
      this.visible = true
      await this.queryOptionsByValue(this.value)
      this.loadData()
      // setTimeout(() => {
      //   this.setTableChecked()
      // }, 2000)
    },
    async loadTableData() {
      if (!this.url.list) {
        this.$message.error('请设置url.list属性!')
        return
      }
      var params = this.getQueryParams()// 查询条件
      this.loading = true
      const res = await getAction(this.url.list, params)
      this.loading = false
      if (res.success) {
        this.dataSource = res.result.content
      }
      return res
    },
    setTableChecked() { // 设置表格选中行
      const table = this.$refs.vxeTable
      if (table) {
        const checkboxRows = []
        this.selectedTable.dataSource.forEach(item => {
          const isCheck = table.isCheckedByCheckboxRow({ [this.rowKey]: item[this.rowKey] })
          if (!isCheck) {
            checkboxRows.push({ [this.rowKey]: item[this.rowKey], ...item })
          }
        })
        checkboxRows.length >= 0 && table.setCheckboxRow(checkboxRows, true)// 翻页时根据右侧选中未选中数据
      }
    },
    // valueWatchHandler(val) {
    //   const values = val || []
    //   this.dataSource.concat(this.selectedTable.dataSource).forEach(data => {
    //     if (values.includes(data[this.valueKey])) {
    //       this.pushIfNotExist(this.selectedRowKeys, data[this.rowKey])
    //     }
    //   })
    // },
    pushIfNotExist(array, value, key) {
      for (const item of array) {
        if (key && (item[key] === value[key])) {
          return false
        } else if (item === value) {
          return false
        }
      }
      array.push(value)
      return true
    },
    queryOptionsByValue(value) {
      if (!value || value.length === 0) {
        return
      }
      // 判断options是否存在value，如果已存在数据就不再请求后台了
      let notExist = false
      for (const val of value) {
        let find = false
        for (const option of this.options_) {
          if (val === option.value) {
            find = true
            break
          }
        }
        if (!find) {
          notExist = true
          break
        }
      }
      if (!notExist) return
      const queryParam = new Criteria()
      queryParam.addCriterions(Object.assign({}, {
        [this.valueKey]: value.join(',')
      }), OPERATOR.IN)
      var param = Object.assign({}, { criteria: queryParam.getEncode() })
      getAction(this.valueUrl || this.listUrl, {
        ...param,
        pageNo: 1,
        pageSize: value.length
      }).then((res) => {
        if (res.success) {
          const dataSource = res.result.content
          this.emitOptions(dataSource, (data) => {
            this.pushIfNotExist(this.selectedRowKeys, data[this.rowKey])
            this.pushIfNotExist(this.selectedTable.dataSource, data, this.rowKey)
          })
        }
      })
    },

    emitOptions(dataSource, callback) { // 回写父组件下拉框option
      dataSource.forEach(data => {
        const key = data[this.valueKey]
        this.dataSourceMap[key] = JSON.parse(JSON.stringify(data))
        this.pushIfNotExist(this.options_, { label: data[this.displayKey || this.valueKey], value: key }, 'value')
        typeof callback === 'function' ? callback(data) : ''
      })
      this.$emit('options', this.options_, this.dataSourceMap)
    },

    /** 完成选择 */
    handleOk() {
      const value = this.selectedTable.dataSource.map(data => data[this.valueKey])
      this.emitOptions(this.selectedTable.dataSource)
      this.$emit('input', value)
      this.$emit('ok', value)
      this.close()
    },

    /** 删除已选择的 */
    handleDeleteSelected(record, index) {
      this.selectedRowKeys.splice(this.selectedRowKeys.indexOf(record[this.rowKey]), 1)
      this.$refs.vxeTable.setCheckboxRow({ [this.rowKey]: record[this.rowKey] }, false) // 右侧取消选中 删除对应的选中行
    },
    onSelectChange({ row, checked, records }) {
      if (this.multiple) {
        const { fullData } = this.$refs.vxeTable.getTableData()
        const checkboxKey = []
        records.forEach(item => { // 选中行在右侧显示
          const rowKey = item[this.rowKey]
          !this.selectedRowKeys.includes(rowKey) && this.selectedRowKeys.push(rowKey)
          checkboxKey.push(rowKey)
        })
        fullData.forEach(item => { // 左侧取消选中，删除右侧已显示的数据
          const rowKey = item[this.rowKey]
          if (!checkboxKey.includes(rowKey) && this.selectedRowKeys.includes(rowKey)) {
            this.selectedRowKeys.splice(this.selectedRowKeys.indexOf(rowKey), 1)
          }
        })
      } else {
        this.selectedRowKeys = []
        const row = this.$refs.vxeTable.getRadioRecord()
        const rowId = this.$refs.vxeTable.getRowid(row)
        this.selectedRowKeys.push(rowId)
      }
    }
  }
}
</script>
<style>
.table-page-search-form .ant-form-item {
  display: flex;
}

.table-page-search-form .ant-form-item-control-wrapper {
  flex: 1;
}
</style>
